from transitions import Machine
from datetime import datetime, timedelta
import time

# 定义状态机的状态
states = [
    'state_off',        # 电源关闭
    'state_heating',    # 正在加热
    'state_at_temp',    # 达到目标温度
    'state_maintenance',# 维修状态
    'state_sleep'       # 休眠状态
]

# 定义状态转换的事件及其条件函数
events = [
    {'trigger': 'start_heating', 'source': 'state_off', 'dest': 'state_heating', 'conditions': 'water_present'},
    {'trigger': 'stop_heating', 'source': ['state_heating', 'state_off'], 'dest': 'state_at_temp', 'conditions': 'temp_100'},
    {'trigger': 'enter_maintenance', 'source': '*', 'dest': 'state_maintenance'},
    {'trigger': 'enter_sleep', 'source': '*', 'dest': 'state_sleep', 'conditions': 'is_night'},
    {'trigger': 'wake_up', 'source': 'state_sleep', 'dest': 'state_off', 'conditions': 'is_morning'}
]

# 定义状态机的条件函数
def water_present(model):
    return model.water_sensor == True

def temp_100(model):
    return model.temperature >= 100

def is_night(model):
    return datetime.now().hour == 23 and datetime.now().minute == 0

def is_morning(model):
    return datetime.now().hour == 7 and datetime.now().minute == 0

# 定义恒温水箱类
class Thermostat:
    def __init__(self):
        self.temperature = 20  # 初始温度设为20°
        self.water_sensor = True  # 初始假设有水
        self.relay_powered = False  # 继电器初始状态为关闭
        self.broken = False  # 初始状态未损坏

        # 初始化状态机
        self.machine = Machine(model=self, states=states, events=events, initial='state_off')

        # 定时检查时间以进入休眠和唤醒状态
        self.check_time_interval = timedelta(minutes=1)
        self.last_time_check = datetime.now() - self.check_time_interval

    def update_temperature(self, new_temp):
        self.temperature = new_temp
        # 自动停止加热当温度达到100°
        if self.temperature >= 100:
            self.stop_heating()

    def check_time(self):
        current_time = datetime.now()
        if (current_time - self.last_time_check) >= self.check_time_interval:
            self.last_time_check = current_time
            if is_night(self):
                self.enter_sleep()
            elif is_morning(self):
                self.wake_up()

    def on_enter_state_heating(self):
        print("Heating...")
        self.relay_powered = True

    def on_exit_state_heating(self):
        print("Stopped heating.")
        self.relay_powered = False

    def on_enter_state_sleep(self):
        print("Entering sleep mode at 11 PM.")

    def on_enter_state_maintenance(self):
        print("Entering maintenance mode.")
        self.broken = True  # 标记为损坏状态

    def on_enter_state_at_temp(self):
        print("Water reached 100°C.")

    def simulate(self, steps=10):
        """
        模拟温度上升过程
        """
        for _ in range(steps):
            if self.state == 'state_heating' and not self.broken:
                self.update_temperature(self.temperature + 1)  # 模拟温度上升
            self.check_time()
            time.sleep(1)  # 等待1秒

# 实例化恒温水箱对象
thermostat = Thermostat()

# 模拟运行
thermostat.start_heating()  # 假设初始时有水，开始加热
thermostat.simulate(steps=20)  # 模拟20步的温度变化

# 手动进入维修状态（假设水箱损坏）
thermostat.enter_maintenance()
thermostat.simulate(steps=5)  # 再模拟5步

# 手动唤醒并重新启动
thermostat.wake_up()
thermostat.water_sensor = True  # 重置水量传感器
thermostat.broken = False  # 重置损坏状态
thermostat.simulate(steps=30)  # 继续模拟